package com.zly;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Path;

public class DJUtils {

    private static final ObjectMapper MAPPER = new ObjectMapper();

    //构造
    private DJUtils() {}

    //将JsonNode的值判定为true或false
    public static boolean isTruthy(JsonNode node) {

        //若JsonNode对应的Json值类型为布尔型
        if(node.isBoolean()){
            return node.asBoolean();
        }else if(node.isNull()){//若JsonNode对应的Json值为null
            return false;
        }else if(node.isNumber()){//若为数值类型

            if(node.isIntegralNumber()){//若为整型
                if(node.isBigInteger()){
                    return !BigInteger.ZERO.equals(node.bigIntegerValue());
                }else{
                    return node.asInt() != 0;
                }
            }else{//若为浮点型
                if(node.isBigDecimal()){
                    return !BigDecimal.ZERO.equals(node.decimalValue());
                }else{
                    return node.asDouble() != 0;
                }
            }

        }else if(node.isTextual()){//若为字符串类型
            return node.asText() != null && !node.asText().isEmpty();
        }else{//其他情况，既为Json对象或为Json数组
            return !node.isEmpty();
        }

    }

    //将Json值从Json数据类型转换为几种特定的Java数据类型，返回该Java数据类型的Object引用
    public static Object convert(JsonNode valueNode){

        //按照Json标准定义的五种Json数据类型区分情况
        if(valueNode.isNull()){
            return null;
        }else if(valueNode.isBoolean()){
            return valueNode.asBoolean();
        }else if(valueNode.isTextual()){
            return valueNode.asText();
        }else if(valueNode.isNumber()){//Json标准不区分整型和浮点型，更不区分整型的长度是int还是long

            //Jackson库的默认行为:Json中的整型数据优先当作Int，若超出大小，当作Long，再超出大小，当作BigInteger。
            //从Json读取的值永远不会当作Short，从Json读取的JsonNode的isShort()方法恒为false，只有使用ObjectNode
            //的相关方法设置值时传入short或Short时，isShort()才返回true
            //而对于浮点型，从Json读取的isDouble()恒为true，isFloat()和isBigDecimal()恒为false

            if(valueNode.isIntegralNumber()){//若为某种整型类型

                if(valueNode.isShort()){
                    return valueNode.shortValue();
                }else if(valueNode.isInt()){
                    return valueNode.intValue();
                }else if(valueNode.isLong()){
                    return valueNode.longValue();
                }else if(valueNode.isBigInteger()){
                    return valueNode.bigIntegerValue();
                }

            }else{//若为某种小数类型

                if(valueNode.isFloat()){
                    return valueNode.floatValue();
                }else if(valueNode.isDouble()){
                    return valueNode.doubleValue();
                }else if(valueNode.isBigDecimal()){
                    return valueNode.decimalValue();
                }
            }

        }else if(valueNode.isObject()){//若为Json对象，返回JsonNode
            return valueNode;
        }else{//若为Json数组，返回JsonNode
            return valueNode;
        }

        throw new RuntimeException("将Json数据类型转换为Object类型时未匹配成功:"+valueNode.toPrettyString());

    }

    //判断目标文件是否能解析为Json
    public static boolean isJson(Path filePath){
        String content = null;{
            try {
                content = Files.readString(filePath);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return isJson(content);
    }

    //判断目标字符串是否能解析为Json
    public static boolean isJson(String content){
        try {
            MAPPER.readTree(content);
        } catch (JsonProcessingException e) {
            return false;
        }
        return true;
    }

}
